package org.dromara.business.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.dromara.business.domain.*;
import org.dromara.business.domain.bo.AdvertisingBo;
import org.dromara.business.domain.vo.AdvertisingVo;
import org.dromara.business.mapper.AdvertisingMapper;
import org.dromara.business.service.AdvertisingService;
import org.dromara.business.service.UserService;
import org.dromara.common.core.constant.UserConstants;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import cn.hutool.core.util.StrUtil;
import org.dromara.common.core.utils.StaticLogger;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.websocket.utils.WebSocketUtils;
import org.dromara.system.domain.SysDept;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 广告Service业务层处理
 *
 * @author zlj
 * @date 2024-12-12
 */
@RequiredArgsConstructor
@Service
public class AdvertisingServiceImpl extends ServiceImpl<AdvertisingMapper, Advertising> implements AdvertisingService {

    private final AdvertisingMapper baseMapper;
    private final UserService userService;
    private final ScheduledExecutorService scheduledExecutorService;

    /**
     * 查询广告
     */
    @Override
    public AdvertisingVo queryById(Long advertisingId){
        return baseMapper.selectVoById(advertisingId);
    }

    /**
     * 查询广告列表
     */
    @Override
    public TableDataInfo<AdvertisingVo> queryPageList(AdvertisingBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<Advertising> lqw = buildQueryWrapper(bo);
        Page<AdvertisingVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询广告列表
     */
    @Override
    public List<AdvertisingVo> queryList(AdvertisingBo bo) {
        LambdaQueryWrapper<Advertising> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<Advertising> buildQueryWrapper(AdvertisingBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<Advertising> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(bo.getCity()), Advertising::getCity, bo.getCity());
        lqw.eq(StrUtil.isNotBlank(bo.getUrl()), Advertising::getUrl, bo.getUrl());
        lqw.eq(StrUtil.isNotBlank(bo.getState()), Advertising::getState, bo.getState());
        lqw.eq(ObjectUtil.isNotNull(bo.getCreateBy()), Advertising::getCreateBy, LoginHelper.getUserId());
        lqw.eq(bo.getNumber() != null, Advertising::getNumber, bo.getNumber());
        lqw.orderByDesc(Advertising::getCreateTime);
        return lqw;
    }

    /**
     * 新增广告
     */
    @Override
    public Boolean insertByBo(AdvertisingBo bo) {
        Advertising add = MapstructUtils.convert(bo, Advertising.class);
        validEntityBeforeSave(bo);

        boolean b = baseMapper.insertOrUpdate(add);
        return b;
    }

    /**
     * 修改广告
     */
    @Override
    public Boolean updateByBo(AdvertisingBo bo) {
        Advertising update = MapstructUtils.convert(bo, Advertising.class);
        validEntityBeforeSave(bo);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(AdvertisingBo entity){

        if (ObjectUtil.isNull(entity.getAdvertisingId())){

            // 如果 url 的字符串包含 "undefined"，上传失败
            if (entity.getUrl().contains("undefined")) {
                throw new ServiceException("广告上传失败");
            }
        }


    }

    /**
     * 批量删除广告
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){

        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }


    @Override
    public TableDataInfo<AdvertisingVo> approveList(AdvertisingBo bo, PageQuery pageQuery) {

        Long userId = LoginHelper.getUserId();
        User byId = userService.getById(userId);
        String proxyRegion = byId.getProxyRegion();
        List<String> list = Arrays.stream(proxyRegion.split(",")).toList();

        LambdaQueryWrapper<Advertising> lqw = Wrappers.lambdaQuery();
        lqw.eq(StrUtil.isNotBlank(bo.getState()), Advertising::getState, bo.getState());
        lqw.in(Advertising::getCity, list);
        Page<AdvertisingVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 审核广告
     * @param bo
     * @return
     */
    @Override
    public Boolean examineAdvertising(AdvertisingBo bo) {
        Advertising update = MapstructUtils.convert(bo, Advertising.class);

        //如果审批通过修改过期时间
        if ("2".equals(  update.getState())){
            // 计算当前时间加上指定天数后的时间
            LocalDateTime currentTime = LocalDateTime.now();
            LocalDateTime newTime = currentTime.plusDays(365);
            Date gqTime = Date.from(newTime.atZone(ZoneId.systemDefault()).toInstant());
            update.setExpirationDate(gqTime);
        }
        update.setUpdateTime(new Date());
        update.setUpdateBy(LoginHelper.getUserId());
        return baseMapper.updateById(update) > 0;
    }

    @Override
    public Long getCountOfRegions(String city) {

        LambdaQueryWrapper<Advertising> lqw = Wrappers.lambdaQuery();
        lqw.eq(Advertising::getCity, city);

        return  baseMapper.selectCount(lqw);


    }

    @Override
    public Long getCityNumber(String city) {
        LambdaQueryWrapper<Advertising> lqw = Wrappers.lambdaQuery();
        lqw.eq(Advertising::getCity, city);
        lqw.eq(Advertising::getState, "2");
        return baseMapper.selectCount(lqw);
    }


    @Override
    public AdvertisingVo watchAdvertisements(String city) {
        QueryWrapper<Advertising> wrapper = new QueryWrapper<>();
        wrapper.eq("city", city);
        wrapper.eq("state", "2");
// 不需要添加 orderByDesc("id")，因为我们想要随机排序
        wrapper.last("ORDER BY RAND() LIMIT 1");
        Advertising advertising = baseMapper.selectOne(wrapper);
        AdvertisingVo advertisingVo = new AdvertisingVo();
        if(advertising != null){
            advertisingVo.setCity(advertising.getCity());
            advertisingVo.setUrl(advertising.getUrl());
        }
        return advertisingVo;
    }

//    /**
//     * 查看广告
//     * @param city
//     * @return
//     */
//        @Override
//        public AdvertisingVo watchAdvertisements(String city) {
//            long currentPage = StaticLogger.getCurrentPage(city);
//            while (true) {
//                IPage<AdvertisingVo> advertisingPage = getAdvertisingPage(city, currentPage);
//                List<AdvertisingVo> records = advertisingPage.getRecords();
//                if (!records.isEmpty()) {
//                    // 如果找到了广告，更新页码并返回第一个广告
//                    StaticLogger.updateCurrentPage(city, currentPage + 1);
//                    return records.get(0);
//                } else if (advertisingPage.getTotal()+1 == currentPage) {
//                    // 这里选择重置页码
//                    currentPage=1;
//                }else if (1==currentPage){
//                    return new AdvertisingVo();
//                }
//                else {
//                    // 如果不是最后一页，则尝试下一页
//                    currentPage++;
//                }
//            }
//
//        }
//
//        public IPage<AdvertisingVo> getAdvertisingPage(String city, long currentPage) {
//            Page<Advertising> page = new Page<>(currentPage,1);
//            LambdaQueryWrapper<Advertising> lqw = Wrappers.lambdaQuery();
//            lqw.eq(Advertising::getCity, city);
//            lqw.eq(Advertising::getState, "2");
//            lqw.orderByDesc(Advertising::getCreateTime);
//            return baseMapper.selectVoPage(page, lqw);
//        }
    }






